﻿using GKS.DataTypes.Math;
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using System.Threading.Tasks;

namespace Tests.Math {
    public static class MatrixTest {
        #region variables

        #endregion

        #region properties

        #endregion

        #region enums

        #endregion

        #region constructors

        #endregion

        #region methods
        public static Matrix CreateRandomMatrix(int rows, int cols){
            Matrix result = new Matrix(cols, rows);
            Random ran = new Random();

            for (int i = 0; i < result.Rows; i++) {
                for (int j = 0; j < result.Columns; j++) {
                    result.NumericElements[j, i] = ran.Next(10);
                }
            }

            return result;
        }

        public static void TestMatrixTranspose() {
            Matrix m = CreateRandomMatrix(4, 2);
            Matrix mT = m.Transpose();

            Console.WriteLine("m:\n{0}", m);
            Console.WriteLine("mT:\n{0}", mT);
        }

        public static void TestMatrixScalarMultiplication() {
            int coefficient = 9;
            Matrix m = CreateRandomMatrix(5, 5);

            Console.WriteLine("m:\n{0}", m);
            Console.WriteLine("m * {0}:\n{1}", coefficient, m.MultiplyNumeric(coefficient));
        }

        public static void TestMatrixMultiplication() {
            Matrix m1 = CreateRandomMatrix(3, 2);
            Matrix m2 = CreateRandomMatrix(2, 4);

            Console.WriteLine("m1:\n{0}", m1);
            Console.WriteLine("m2:\n{0}", m2);
            Console.WriteLine("m1 x m2:\n{0}", m1.Multiply(m2));
        }

        public static void TestMatrixTrace() {
            Matrix m = CreateRandomMatrix(10, 10);

            Console.WriteLine("m:\n{0}", m);
            Console.WriteLine("trace(m):\n{0}", m.GetNumericTrace());
        }

        public static void TestMatrixDeterminant() {
            Matrix m = CreateRandomMatrix(10, 10);

            Console.WriteLine("m:\n{0}", m);
            Console.WriteLine("Det(m):\n{0}", m.GetNumericDeterminant());
        }

        public static void TestMatrixToString() {
            //Matrix m1 = new Matrix(columns: 9, rows: 5);
            //int n = 0;

            //for (int i = 0; i < m1.Rows; i++) {
            //    for (int j = 0; j < m1.Columns; j++, n++) {
            //        m1.Elements[j, i] = n;
            //    }
            //}

            //string m1s = m1.ToString();
            Matrix m1 = CreateRandomMatrix(5, 9);
            Console.Write(m1.ToString());
        }

        public static void TestMatrixAddition() {
            Matrix m1 = CreateRandomMatrix(3, 3);
            Matrix m2 = CreateRandomMatrix(3, 3);

            Console.WriteLine("m1:\n{0}", m1.ToString());
            Console.WriteLine("m2:\n{0}", m2.ToString());
            Console.WriteLine("m1 + m2:\n{0}", m1.Add(m2).ToString());
        }

        public static void TestMatrixAsyncAddition() {
            Matrix m1 = CreateRandomMatrix(10, 10);
            Matrix m2 = CreateRandomMatrix(10, 10);
            Task<Matrix> tm = m1.AddAsync(m2);

            Console.WriteLine("m1:\n{0}", m1);
            Console.WriteLine("m2:\n{0}", m2);
            tm.Wait();
            Console.WriteLine("Async(m1 + m2):\n{0}", tm.Result);
        }

        public static void TestMatrixEquality() {
            Matrix m1 = CreateRandomMatrix(5, 6);
            Matrix m2 = CreateRandomMatrix(7, 5);
            Matrix m3 = m1;

            Console.WriteLine("m1 == m2: {0}", m1.Equals(m2));
            Console.WriteLine("m2 == m3: {0}", m2.Equals(m3));
            Console.WriteLine("m1 == m3: {0}", m1.Equals(m3));
        }
        #endregion
    }
}
